﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SGS.Standard;
using System.Net.Sockets;

namespace SGSGameServer
{
    public class SocketPool
    {
        public class SocketInfo
        {
            public SocketInfo( Socket socket )
            {
                Socket = socket;
                DataBuffer = new byte[1024];
                DataLengthBuffer = new byte[4];
            }

            public Socket Socket
            {
                get;
                set;
            }

            public byte[] DataBuffer
            {
                get;
                set;
            }

            public byte[] DataLengthBuffer
            {
                get;
                set;
            }

            public Player MappingPlayer
            {
                get;
                set;
            }

            public string AuthorizationUserName
            {
                get;
                set;
            }

            public bool IsAuthenticated
            {
                get
                {
                    return string.IsNullOrEmpty( AuthorizationUserName );
                }
            }
        }

        static SocketPool _poolinstance = null;

        public static SocketPool Instance
        {
            get
            {
                if (_poolinstance == null)
                {
                    _poolinstance = new SocketPool();
                }
                return _poolinstance;
            }
        }

        private SocketPool()
        {
            _PlayerSocketPool = new Dictionary<Player, SocketInfo>();
            _SocketPool = new Dictionary<Socket, SocketInfo>();
        }

        static Dictionary<Socket, SocketInfo> _SocketPool = null;
        static Dictionary<Player, SocketInfo> _PlayerSocketPool = null;

        //private Dictionary<Player, Socket> _PlayerSocketsPool = null;
        //private Dictionary<string, Socket> _UniqueIDSocketPool = null;
        //private Dictionary<Socket, byte[]> _SocketBuffer = null;

        internal void DisconnectSocket( Socket socket )
        {
            if (socket.Connected)
            {
                socket.Close();
                socket.Dispose();
            }

            if (_SocketPool.ContainsKey( socket ))
            {
                var info = _SocketPool[socket];
                _SocketPool.Remove( socket );

                if (info.MappingPlayer != null)
                {
                    _PlayerSocketPool.Remove( info.MappingPlayer );
                }
            }
        }

        internal void DisconnectSocket( Player player )
        {
            if (!_PlayerSocketPool.ContainsKey( player ))
            {
                return;
            }

            var info = _PlayerSocketPool[player];
            DisconnectSocket( info.Socket );
        }

        internal SocketInfo AddSocket( Socket socket, Player player = null )
        {
            if (!_SocketPool.ContainsKey( socket ))
            {
                _SocketPool.Add( socket, new SocketInfo( socket ) );
            }

            if (player != null && !_PlayerSocketPool.ContainsKey( player ))
            {
                _PlayerSocketPool.Add( player, _SocketPool[socket] );
            }

            return _SocketPool[socket];
        }

        public SocketInfo GetSocketInfo( Socket socket )
        {
            return _SocketPool[socket];
        }
    }
}
